package com.template.common.util;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.template.common.constant.CommonConstant;

import java.util.List;

/**
 * 分页工具类
 * 
 * @author template
 * @since 2024-01-01
 */
public class PageUtil {

    /**
     * 创建分页对象
     * 
     * @param pageNum 页码
     * @param pageSize 页大小
     * @param <T> 泛型
     * @return 分页对象
     */
    public static <T> Page<T> createPage(Integer pageNum, Integer pageSize) {
        if (pageNum == null || pageNum < 1) {
            pageNum = CommonConstant.DEFAULT_PAGE_NUM;
        }
        if (pageSize == null || pageSize < 1) {
            pageSize = CommonConstant.DEFAULT_PAGE_SIZE;
        }
        if (pageSize > CommonConstant.MAX_PAGE_SIZE) {
            pageSize = CommonConstant.MAX_PAGE_SIZE;
        }
        return new Page<>(pageNum, pageSize);
    }

    /**
     * 创建分页对象（带排序）
     * 
     * @param pageNum 页码
     * @param pageSize 页大小
     * @param orderBy 排序字段
     * @param orderDirection 排序方向
     * @param <T> 泛型
     * @return 分页对象
     */
    public static <T> Page<T> createPage(Integer pageNum, Integer pageSize, String orderBy, String orderDirection) {
        Page<T> page = createPage(pageNum, pageSize);
        
        if (orderBy != null && !orderBy.trim().isEmpty()) {
            // 处理排序方向
            boolean isAsc = CommonConstant.ORDER_ASC.equalsIgnoreCase(orderDirection);
            page.addOrder(isAsc ? OrderItem.asc(orderBy) : OrderItem.desc(orderBy));
        } else {
            // 默认排序
            page.addOrder(OrderItem.desc(CommonConstant.DEFAULT_ORDER_BY));
        }
        
        return page;
    }

    /**
     * 转换分页结果
     * 
     * @param page MyBatis Plus分页对象
     * @param <T> 泛型
     * @return 分页结果
     */
    public static <T> PageResult<T> convertPageResult(IPage<T> page) {
        PageResult<T> result = new PageResult<>();
        result.setList(page.getRecords());
        result.setTotal(page.getTotal());
        result.setPageNum((int) page.getCurrent());
        result.setPageSize((int) page.getSize());
        result.setPages(page.getPages());
        result.setHasNextPage(page.getCurrent() < page.getPages());
        result.setHasPreviousPage(page.getCurrent() > 1);
        return result;
    }

    /**
     * 分页结果封装类
     */
    public static class PageResult<T> {
        /**
         * 数据列表
         */
        private List<T> list;
        
        /**
         * 总记录数
         */
        private Long total;
        
        /**
         * 当前页码
         */
        private Integer pageNum;
        
        /**
         * 页大小
         */
        private Integer pageSize;
        
        /**
         * 总页数
         */
        private Long pages;
        
        /**
         * 是否有下一页
         */
        private Boolean hasNextPage;
        
        /**
         * 是否有上一页
         */
        private Boolean hasPreviousPage;

        // Getters and Setters
        public List<T> getList() {
            return list;
        }

        public void setList(List<T> list) {
            this.list = list;
        }

        public Long getTotal() {
            return total;
        }

        public void setTotal(Long total) {
            this.total = total;
        }

        public Integer getPageNum() {
            return pageNum;
        }

        public void setPageNum(Integer pageNum) {
            this.pageNum = pageNum;
        }

        public Integer getPageSize() {
            return pageSize;
        }

        public void setPageSize(Integer pageSize) {
            this.pageSize = pageSize;
        }

        public Long getPages() {
            return pages;
        }

        public void setPages(Long pages) {
            this.pages = pages;
        }

        public Boolean getHasNextPage() {
            return hasNextPage;
        }

        public void setHasNextPage(Boolean hasNextPage) {
            this.hasNextPage = hasNextPage;
        }

        public Boolean getHasPreviousPage() {
            return hasPreviousPage;
        }

        public void setHasPreviousPage(Boolean hasPreviousPage) {
            this.hasPreviousPage = hasPreviousPage;
        }
    }
}
